package com.mcxx.modules.miniSalvation.fundpay.service.read;

import com.mcxx.common.exception.BizException;
import com.mcxx.constant.DictConstant;
import com.mcxx.modules.base.service.read.AreaHelper;
import com.mcxx.modules.base.service.read.DictionaryReadService;
import com.mcxx.modules.base.utils.QueryParamUtil;
import com.mcxx.modules.miniSalvation.fundpay.dao.read.FundPayMemberReadDao;
import com.mcxx.modules.miniSalvation.fundpay.dao.read.FundPayReadDao;
import com.mcxx.modules.miniSalvation.fundpay.dto.*;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayEntity;
import com.mcxx.modules.miniSalvation.fundpay.entity.FundPayStatusEntity;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayListSearchParam;
import com.mcxx.modules.miniSalvation.fundpay.param.FundPayParam;
import com.mcxx.modules.miniSalvation.fundpay.param.MonitorDataParam;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayReadService;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.DateUtil;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.component.org.orguser.area.entity.TaAreaPo;
import com.yinhai.ta404.component.org.orguser.area.service.read.AreaManagementReadService;
import com.yinhai.ta404.core.restservice.requestbean.PageParam;
import com.yinhai.ta404.core.restservice.resultbean.Page;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.module.dict.entity.TaDictPo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("fundPayReadService")
@TaTransactional(readOnly = true)
public class FundPayReadService extends BaseService {

    private static final Logger logger = LoggerFactory.getLogger(FundPayReadService.class);

    @Autowired
    private FundPayReadDao fundPayReadDao;
    @Autowired
    private AreaManagementReadService areaManagementReadService;
    @Autowired
    private DictionaryReadService dictionaryReadService;
    @Autowired
    private AreaHelper areaHelper;
    @Autowired
    private TmpFundPayReadService tmpFundPayReadService;
    @Autowired
    private FundPayMemberReadDao fundPayMemberReadDao;




    public List<FundPayEntity> listAll(FundPayParam param){
        return fundPayReadDao.listAll(param);
    }


    public FundPayEntity isCanOperate(String fundPayId,  List<String> stateList){
        FundPayEntity fundPayEntity = fundPayReadDao.getById(fundPayId);
        if(!stateList.contains(fundPayEntity.getStatus())){
            TaDictPo taDictPo = dictionaryReadService.getCodeCache(DictConstant.PAYMENT_MANNER, fundPayEntity.getStatus());
            throw new BizException("-1", "当前名册状态为[" + taDictPo.getLabel() + "]无法执行此操作");
        }
        return fundPayEntity;
    }



    public Page getFundPayList(FundPayListSearchParam fundPayListSearchParam, PageParam pageParam, UserAccountVo userAccountVo){

        QueryParamUtil.setBaseParamValue(fundPayListSearchParam, userAccountVo);

        fundPayReadDao.beginPager(pageParam);
        List<FundPayEntity> fundPayEntityList = fundPayReadDao.getFundPayList(fundPayListSearchParam);

        return fundPayReadDao.endPager(fundPayEntityList);
    }


    public List<FundPayEntity> getFundPayList(FundPayListSearchParam fundPayListSearchParam){
        return fundPayReadDao.getFundPayList(fundPayListSearchParam);
    }


    public void cntFundPayThrow(FundPayDTO fundPayDTO){
        if(StringUtils.isEmpty(fundPayDTO.getQueryType())){
            fundPayDTO.setQueryType("0");
        }
        String rst = fundPayReadDao.cntFundPay(fundPayDTO);
        if(StringUtils.isNotBlank(rst)){

            throw new BizException(FailureCode.ERR_10044);
        }
    }


    public void cntFundPayByOrderId(FundPayDTO fundPayDTO){
        if(StringUtils.isEmpty(fundPayDTO.getQueryType())){
            fundPayDTO.setQueryType("0");
        }
        String rst = fundPayReadDao.cntFundPayByOrderId(fundPayDTO);
        if(StringUtils.isNotBlank(rst)){

            throw new BizException("-1", "名册已经存在，该数据不可撤销！");
        }
    }


    public void verifyFundPayThrow(String businessType, String countryCode, String standType, String payDate, String supplyType, String fundType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            payDate = payDate.length() > 7 ? payDate : payDate.contains("-") ? payDate + "-01" : payDate.substring(0,4) + "-" + payDate.substring(4) + "-01";
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("0");
        this.cntFundPayThrow(fundPayDTO);
    }

    public void verifyFundPayByOrderId(String businessType, String countryCode, String standType, String payDate, String supplyType, String fundType,String orderId){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("0");
        fundPayDTO.setRemark(orderId);
        this.cntFundPayByOrderId(fundPayDTO);
    }


    public String verifyFundPay(String businessType, String countryCode, String standType, String payDate, String supplyType, String fundType, String queryType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            payDate = payDate.length() > 7 ? payDate : payDate.contains("-") ? payDate + "-01" : payDate.substring(0,4) + "-" + payDate.substring(4) + "-01";
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType(queryType);
        return fundPayReadDao.cntFundPay(fundPayDTO);
    }

    public String verifySuspendFundPay(String orderId,String businessType, String countryCode, String standType, String payDate, String supplyType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            payDate = payDate.length() > 7 ? payDate : payDate.contains("-") ? payDate + "-01" : payDate.substring(0,4) + "-" + payDate.substring(4) + "-01";
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setOrderId(orderId);
        return fundPayReadDao.getFundMaxDateWithOrderId(fundPayDTO);
    }

    public void verifySuspendFundPayThrow(String orderId,String businessType, String countryCode, String standType, String payDate, String supplyType){
       String maxMonth = verifySuspendFundPay(orderId,businessType,countryCode,standType,payDate,supplyType);
       if(StringUtils.isNotBlank(maxMonth)){

           throw new BizException(FailureCode.ERR_10044);
       }
    }

    public Map<String, List<String>> getIdByIdAndStates(List<String> fundPayIdList, List<String> stateList){
        Map<String, List<String>> rstMap = new HashMap<>();

        List<String> canDelIdList = fundPayReadDao.getIdByIdsAndStates(fundPayIdList, stateList);
        if(canDelIdList.size() == fundPayIdList.size()){

            rstMap.put("success", canDelIdList);
            return rstMap;
        }
        if(canDelIdList.size() == 0){

            rstMap.put("fail", fundPayIdList);
            return rstMap;
        }

        List<String> canNotDelIdList = fundPayIdList.stream().filter(id -> canDelIdList.contains(id) == false).collect(Collectors.toList());
        rstMap.put("success", canDelIdList);
        rstMap.put("fail", canNotDelIdList);
        return rstMap;
    }


    public Map<String, List<String>> getIdByIdAndState(List<String> fundPayIdList, String state){
        Map<String, List<String>> rstMap = new HashMap<>();

        List<String> successIdList = fundPayReadDao.getIdByIdsAndState(fundPayIdList, state);
        if(successIdList.size() == fundPayIdList.size()){

            rstMap.put("success", successIdList);
            return rstMap;
        }
        if(successIdList.size() == 0){

            rstMap.put("fail", fundPayIdList);
            return rstMap;
        }

        List<String> failIdList = fundPayIdList.stream().filter(id -> successIdList.contains(id) == false).collect(Collectors.toList());
        rstMap.put("success", successIdList);
        rstMap.put("fail", failIdList);
        return rstMap;
    }

    public String verifyFundPayFuneralThrow(String businessType, String countryCode, String standType, Date payDate, String recevierType, String fundType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);

        fundPayDTO.setPayDate(payDate);
        fundPayDTO.setRecevierType(recevierType);
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("0");
        return fundPayReadDao.cntFundPay(fundPayDTO);
    }


    public String verifyFundPayCareThrow(String businessType, String countryCode, String standType, Date payDate, String caregiverType, String fundType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        fundPayDTO.setPayDate(payDate);
        fundPayDTO.setCaregiverType(caregiverType);
        fundPayDTO.setSupplyType("02");
        fundPayDTO.setCostType("330");
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("0");
        return fundPayReadDao.cntFundPay(fundPayDTO);
    }


    public String verifyFundPayStopCareThrow(String businessType, String countryCode, String standType, String payDate, String supplyType, String fundType){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            payDate = payDate.length() > 7 ? payDate : payDate.contains("-") ? payDate + "-01" : payDate.substring(0,4) + "-" + payDate.substring(4) + "-01";
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setCostType("330");
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("1");
        return fundPayReadDao.cntFundPay(fundPayDTO);
    }








    public void cntCapitalFundPay(CapitalFundPayDTO capitalFundPayDTO){
        FundPayDTO fundPayDTO = new FundPayDTO();
        BeanUtils.copyProperties(capitalFundPayDTO, fundPayDTO);
        this.cntFundPayThrow(fundPayDTO);
    }







    public void cntStand(StandFundPayDTO standFundPayDTO){
        FundPayDTO fundPayDTO = new FundPayDTO();
        BeanUtils.copyProperties(standFundPayDTO, fundPayDTO);
        this.cntFundPayThrow(fundPayDTO);
    }






    public void cntAllowance(AllowanceFundPayDTO allowanceFundPayDTO){
        FundPayDTO fundPayDTO = new FundPayDTO();
        BeanUtils.copyProperties(allowanceFundPayDTO, fundPayDTO);
        this.cntFundPayThrow(fundPayDTO);
    }


    public FundPayEntity getById(String fundPayId){
        return fundPayReadDao.getById(fundPayId);
    }


    public Integer checkFundPayCanAddMember(String fundPayId){
        return fundPayReadDao.checkFundPayCanAddMember(fundPayId);
    }








    public void cntCustom(CustomFundPayDTO customFundPayDTO){
        FundPayDTO fundPayDTO = new FundPayDTO();
        BeanUtils.copyProperties(customFundPayDTO, fundPayDTO);
        this.cntFundPayThrow(fundPayDTO);
    }









    public void cntFuneral(FuneralFundPayDTO funeralFundPayDTO){
        FundPayDTO fundPayDTO = new FundPayDTO();
        BeanUtils.copyProperties(funeralFundPayDTO, fundPayDTO);
        this.cntFundPayThrow(fundPayDTO);
    }





    public Page getMonitorDataList(MonitorDataParam param, PageParam pageParam, UserAccountVo userAccountVo) {
        param.setTokenAreaCode(QueryParamUtil.setAreaCodeByLevel(userAccountVo.getAreaCode(), Integer.valueOf(userAccountVo.getAreaLevel())));
        if(!CommonUtil.invalidArgs(param.getAddressCode())){
            TaAreaPo taAreaPo=areaManagementReadService.queryAreaByAreaCode(param.getAddressCode());
            param.setAddressCode(QueryParamUtil.setAreaCodeByLevel(param.getAddressCode(),taAreaPo.getAreaLevel()));
        }
         fundPayReadDao.beginPager(pageParam);
        List<MonitorDataDTO> fundPayEntities=fundPayReadDao.getMonitorDataList(param);
        for (MonitorDataDTO mnitorDataDTO: fundPayEntities){
          AreaHelper.AreaPo  areaPo=areaHelper.getAreaByCode(mnitorDataDTO.getAreaCode());
            mnitorDataDTO.setCity(areaPo.getCity());
            mnitorDataDTO.setCounty(areaPo.getCounty());
            mnitorDataDTO.setType(Constant.MonitorState.UN_CONFIRM);
        }
        return fundPayReadDao.endPager(fundPayEntities);
    }


    public List<FundPayExcelDto> exportFundPayList(FundPayParam param){ return fundPayReadDao.exportFundPayList(param); }

    public List<FundPayEntity> getFundPayByMonth(String fundType, String areaCode, String payDate, String businessType){
        return fundPayReadDao.getFundPayByMonth(fundType, areaCode, payDate, businessType);
    }

    public List<FundPayStatusEntity> getFundpayCreate(String areaCode, String month, String preMonth){
        return fundPayReadDao.getFundpayCreate(areaCode, month, preMonth);
    }


    public void verifyConfirmFundPayThrow(String businessType, String countryCode, String standType, String payDate, String supplyType, String fundType,String status){
        FundPayDTO fundPayDTO = new FundPayDTO();
        fundPayDTO.setBusinessType(businessType);
        fundPayDTO.setAreaCode(countryCode.substring(0,6) + "000000");
        fundPayDTO.setStandType(standType);
        try {
            payDate = payDate.length() > 7 ? payDate : payDate.contains("-") ? payDate + "-01" : payDate.substring(0,4) + "-" + payDate.substring(4) + "-01";
            fundPayDTO.setPayDate(DateUtil.sdf2.parse(payDate));
        } catch (ParseException e) {
            throw new BizException("-1", "日期格式转换失败");
        }
        fundPayDTO.setSupplyType(supplyType);
        fundPayDTO.setFundType(fundType);
        fundPayDTO.setQueryType("0");
        fundPayDTO.setStatus(status);
        if(StringUtils.isEmpty(fundPayDTO.getQueryType())){
            fundPayDTO.setQueryType("0");
        }
        String rst = null;
        if(!Constant.BusinessCode.LINSHI.equals(businessType)){
             rst = fundPayReadDao.cntFundPay(fundPayDTO);
        }else{
            rst = tmpFundPayReadService.cntFundPay(fundPayDTO);
        }

        if(StringUtils.isBlank(rst)){

            throw new BizException(FailureCode.ERR_100021);
        }
    }



    public void cntMemberByCreateFuneralOld(FuneralFundPayDTO funeralFundPayDTO, UserAccountVo userAccountVo) {
        QueryParamUtil.setBaseParamValue(funeralFundPayDTO, userAccountVo);
        int rst = fundPayMemberReadDao.cntMemberByCreateFuneralOld(funeralFundPayDTO);
        if(rst <= 0){

            throw new BizException("-1", "名册为空，无法生成");
        }
    }


    public List<FundPayStatusEntity> getCapitalFundPayCreate(String areaCode, String payDate) {
        return fundPayReadDao.getCapitalFundPayCreate(areaCode, payDate);
    }


    public List<FundPayStatusEntity> getHasSaveObjectZone(String areaCode, String payDate) {
        return fundPayReadDao.getHasSaveObjectZone(areaCode, payDate);
    }


    public List<FundPayStatusEntity> getTempHasSaveObjectZone(String validCode, String payDate) {
        return fundPayReadDao.getTempHasSaveObjectZone(validCode, payDate);
    }

    public List<FundPayEntity> getTempFundPay(FundPayListSearchParam param) {
        return fundPayReadDao.getTempFundPay(param);
    }
}
